<?php

namespace Kanin\Games\app;

use Kanin\Games\gameServer;
use Kanin\Games\lib\Config;
use Kanin\Games\model\User;
use Swoole\WebSocket\Frame;
use Swoole\WebSocket\Server;

class UserController extends BaseController {

	/**
	 * 登录
	 * @param \Swoole\WebSocket\Server $server
	 * @param \Swoole\WebSocket\Frame $frame
	 * @return false|string
	 * @throws \Kanin\MyTools\Exception\KMongoException
	 * @throws \MongoDB\Driver\Exception\Exception|\RedisException
	 */
	public function login(Server $server, Frame $frame) {
		$data = json_decode($frame->data, true);
		$user = new User();
		if (empty($data['token'])) {
			if (empty($data['username']) || empty($data['password'])) {
				return $this->responseJson(0x101, ['code' => 101001]);
			}
			$find = $user->findByUsername($data['username']);
			if (!$find) {
				return $this->responseJson(0x101, ['code' => 101002]);
			}
			if (!password_verify($data['password'], $find->password)) {
				return $this->responseJson(0x101, ['code' => 101003]);
			}
			$uid = $find->uid;
			$token = $user->makeToken($uid);
		} else {
			$decode = $user->decodeToken($data['token']);
			if (!$decode) {
				return $this->responseJson(0x101, ['code' => 101004]);
			}
			$uid = $decode['uid'];
			$find = $user->find($uid);
			$token = $data['token'];
		}
		gameServer::$fdTable[$frame->fd]['uid'] = $uid;
		gameServer::$userTable[$uid]['uid'] = $uid;
		$config = Config::get('level', 'level');
		//设置定时任务
		swoole_timer_tick(5000, function ($timer_id) use ($server, $frame, $uid, $config) {
			$user = new User();
			$find = $user->find($uid);
			$nickname = $find->nickname ?? '未知';
			if (isset(gameServer::$fdTable[$frame->fd])) {
				gameServer::$fdTable[$frame->fd]['timer_id'] = $timer_id;
				gameServer::$userTable[$uid]['timer_id'] = $timer_id;
				$expInfo = $user->addExp($uid);
				$level = $find->level ?? 1;
				$levelInfo = $config[$level];
				$msg = [
					'cmd' => 0x102,
					'data' => [
						'exp' => $expInfo['exp'],
						'addExp' => $expInfo['addExp'],
						'uid' => $uid,
						'levelName' => $levelInfo['name'],
						'up' => $levelInfo['up'],
						'nickname' => $nickname,
					]
				];
				$server->push($frame->fd, json_encode($msg));
			}
		});

		$exp = $user->userExp($uid);
		$level = $find->level ?? 1;
		$levelInfo = $config[$level];
		return $this->responseJson(0x101, [
			'code' => 0,
			'token' => $token,
			'nickname' => $find->nickname,
			'exp' => $exp,
			'addExp' => $levelInfo['inc'],
			'levelName' => $levelInfo['name'],
			'up' => $levelInfo['up'],
		]);
	}

	/**
	 * 升级
	 * @param \Swoole\WebSocket\Server $server
	 * @param \Swoole\WebSocket\Frame $frame
	 * @return false|string
	 * @throws \Kanin\MyTools\Exception\KMongoException
	 * @throws \MongoDB\Driver\Exception\Exception|\RedisException
	 */
	public function upLevel(Server $server, Frame $frame) {
		$userModel = new User();
		$uid = gameServer::$fdTable[$frame->fd]['uid'];
		$user = $userModel->find($uid);
		$config = Config::get('level', 'level');
		$level = $user->level ?? 1;
		$config = $config ?? [];
		$maxLevel = max(array_column($config, 'level'));

		if ($config[$level]['up'] > $userModel->userExp($uid)) {
			return $this->responseJson(0x103, ['code' => 102001]);
		}
		$newLevel = $level + 1;
		if ($newLevel > $maxLevel) {
			return $this->responseJson(0x103, [
				'code' => 102003,
			]);
		}
		$upData = [
			'level' => $newLevel
		];
		$res = $userModel->update($upData, $uid);
		if (!$res->getMatchedCount()) {
			return $this->responseJson(0x103, ['code' => 102002]);
		}

		return $this->responseJson(0x103, [
			'code' => 0,
			'levelName' => $config[$newLevel]['name'],
			'exp' => $userModel->userExp($uid),
			'up' => $config[$newLevel]['up'],
			'inc' => $config[$newLevel]['inc'],
		]);
	}
}